package eval.vm;

/**
 * This class represents a single VM instance.
 * 
 * @author Amit Peled   <amit.kapina@gmail.com>
 * @author Igal Kaufman <igal.kaufman@gmail.com>
 */
public class VirtualMachine {

	private eval.vm.VMIdentifier VMIdentifier;
	private VMConfigurationEnum vmConfigurationEnum;
	private VMConfiguration vmConfiguration;
	private int startLifeTimeAtTick;
	private int lifeTime;
	private int satisfiedCpuDemand;
	private int satisfiedMemDemand;


	/**
	 * 
	 * @Constructor
	 * @param identifier VM id
	 * @param vmConfigurationEnum  VM type
	 * @param vmConfiguration VM configuration 
	 * @param lifeTime number of Ticks
	 */
	VirtualMachine(int identifier, VMConfigurationEnum vmConfigurationEnum,
			VMConfiguration vmConfiguration,int lifeTime) {
		this.VMIdentifier = new VMIdentifier(identifier);
		this.vmConfigurationEnum = vmConfigurationEnum;
		this.vmConfiguration = vmConfiguration;
		this.lifeTime = lifeTime;
		this.startLifeTimeAtTick = -1;
	}

	/**
	 * Get VM id
	 * 
	 * @return VM id
	 */
	public VMIdentifier getIdentifier() {
		return VMIdentifier;
	}

	/**
	 * Get VM Type
	 * 
	 * @return VM type
	 */
	public VMConfigurationEnum getVMConfigurationEnum() {
		return vmConfigurationEnum;
	}

	/**
	 * Get VM configuration
	 * 
	 * @return VM configuration
	 */
	public VMConfiguration getVMConfiguration() {
		return vmConfiguration;
	}

	/**
	 * Get VM life time
	 * 
	 * @return number of ticks
	 */
	public int getLifeTime() {
		return lifeTime;
	}

	/**
	 * get Start Life
	 * 
	 * @return Start Life
	 */
	public int getStartLife(){
		return startLifeTimeAtTick;
	}

	/**
	 * set Start Life
	 * 
	 * @param tick the first tick of VM
	 */
	public void setStartLifeAtTick(int tick) {
		this.startLifeTimeAtTick = tick;
	}

	/**
	 * get satisfied CPU Demand
	 * 
	 * @return satisfied CPU
	 */
	public int getSatisfiedCpuDemand() {
		return satisfiedCpuDemand;
	}

	/**
	 * set Satisfied CPU Demand
	 * 
	 * @param satisfiedCpuDemand
	 */
	public void setSatisfiedCpuDemand(int satisfiedCpuDemand) {
		this.satisfiedCpuDemand = satisfiedCpuDemand;
	}

	/**
	 * update Satisfied CPU Demand
	 * 
	 * @param satisfiedCpuDemand
	 */
	public void updateSatisfiedCpuDemand(int satisfiedCpuDemand) {
		this.satisfiedCpuDemand += satisfiedCpuDemand;
	}

	/**
	 * get satisfied MEM Demand
	 * 
	 * @return satisfied MEM
	 */
	public int getSatisfiedMemDemand() {
		return satisfiedMemDemand;
	}

	/**
	 * set Satisfied MEM Demand
	 * 
	 * @param satisfiedMemDemand
	 */
	public void setSatisfiedMemDemand(int satisfiedMemDemand) {
		this.satisfiedMemDemand = satisfiedMemDemand;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((VMIdentifier == null) ? 0 : VMIdentifier.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		VirtualMachine other = (VirtualMachine) obj;
		if (VMIdentifier == null) {
			if (other.VMIdentifier != null)
				return false;
		} else if (!VMIdentifier.equals(other.VMIdentifier))
			return false;
		return true;
	}

}
